<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>拖拽</title>
    <style>
        *{
            padding:0;
            margin:0;
        }
        html,body,.box{
            width: 100%;
            height:100%;
            overflow: hidden;
        }
        .box{
            position: relative;
        }

        .shadow{
            width:100px;
            height: 100px;
            background: orange;
            /* border-radius: 50%; */
            position: absolute;
            top:50px;
            left:50px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    
    <div class="shadow"></div>
    <div class="shadow"></div>
    <div class="shadow"></div>
    <div class="shadow"></div>
    <div class="shadow"></div>
    <div class="shadow"></div>
    <div class="shadow"></div>
    <div class="shadow"></div>
    <script>
        // 工厂模式    批量生产 可以同时返回多个 this 对象  
        // 单例模式    单个模式  一次只有一个 this 对象  多个单例组成工厂模式 (混合模式)




        // 元素拖拽
        // 1. 先按下
        // 2. 鼠标滑动  改变对应的位置  left top
        // 3. 鼠标离开   松开  不再移动
        var shadow = document.getElementsByClassName('shadow')[0];
        var clientWidth = document.documentElement.clientWidth || document.body.clientWidth;
        var clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
        var maxLeft = clientWidth - shadow.clientWidth;    // 可以拖拽的 宽度
        var maxTop = clientHeight - shadow.clientHeight;  // 可以拖拽的 高度 

        // dragStart  x,y 这2个变量传递给 dragMove
        // dragMove
        // dragEnd

        // 改写构造函数  单例模式  
        // prototype 原型对象   提出公共的函数方法 

        // 构造函数  (构造器 + 原型对象  +  静态对象) this 千变万化 时刻记住 this的指向问题 
        function DragFunc(ele){
            this.target = ele;
            this.x = 0;
            this.y = 0;
            this.init();
        }
        // DragFunc.prototype =  this = DragFunc  = 实例化对象
        DragFunc.prototype.init = function(){
            this.randColor();
            var _this = this;
            this.target.onmousedown = function(e){
                // console.log("init - init ",this)
                // this ?
                _this.dragStart(e);
            }
        }
        DragFunc.prototype.dragStart = function(e){
            // this == DragFunc  == 实例化对象
            var e = e || window.event;
            this.x = e.clientX - this.target.offsetLeft;
            this.y = e.clientY - this.target.offsetTop;
            this.dragMove();
            this.dragEnd();
        }
        DragFunc.prototype.dragMove = function(){
            var _this =  this;
            document.onmousemove = function(e){
                // console.log(this)  
                var e = e || window.event;
                var left = e.clientX - _this.x;
                var top = e.clientY - _this.y;

                if(left<0) left = 0;
                if(left>maxLeft) left = maxLeft;
                if(top<0) top = 0;
                if(top>maxTop) top = maxTop;

                _this.target.style.top = top + 'px'
                _this.target.style.left = left + 'px'

            }
        }
        DragFunc.prototype.dragEnd = function(){
            document.onmouseup = function(){
                document.onmouseup = null
                document.onmousemove = null 
            }
        }
        DragFunc.prototype.randColor = function(){
            var colorStr = "0123456789abcdef";
            var color = "#";
            for(var i=0;i<6;i++){
                var index = Math.floor(Math.random() * colorStr.length );
                var char = colorStr.charAt(index);
                console.log(char);
                color += char;
            }
            this.target.style.background = color;
        }



        DragFunc.id = '2107'

        // var obj = new DragFunc(shadow);
        
        var slist = document.getElementsByClassName("shadow");
        for(var i=0;i<slist.length;i++){
            // var sdbox = slist[i];
            // DragFunc(sdbox);
            var obj = new DragFunc(slist[i]);  // this = obj
            
        }
       


        // 换成构造函数 
    </script>
</body>
</html>